{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "lined-crack",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from tensorflow.keras import layers, datasets\n",
    "from tensorflow.keras import Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "divine-alberta",
   "metadata": {},
   "outputs": [],
   "source": [
    "(x_train, y_train), (x_test, y_test)=datasets.cifar10.load_data()\n",
    "x_train = (x_train-x_train.mean())/x_train.std()\n",
    "x_test = (x_test-x_test.mean())/x_test.std()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "circular-fiction",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((50000, 32, 32, 3), (50000, 1), (10000, 32, 32, 3), (10000, 1))"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_train.shape,y_train.shape,x_test.shape,y_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "spectacular-printing",
   "metadata": {},
   "outputs": [],
   "source": [
    "class CBR(Model):\n",
    "    def __init__(self, filters, *args, **kwargs):\n",
    "        super().__init__(*args, **kwargs)\n",
    "        self.conv = layers.Conv2D(\n",
    "            filters=filters, kernel_size=3, padding='same', use_bias=False)\n",
    "        self.bn = layers.BatchNormalization(momentum=0.9, epsilon=1e-5)\n",
    "        self.act = layers.ReLU()\n",
    "\n",
    "    def call(self, x):\n",
    "        x = self.conv(x)\n",
    "        x = self.bn(x)\n",
    "        x = self.act(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "inclusive-charter",
   "metadata": {},
   "outputs": [],
   "source": [
    "class ResBlock(Model):\n",
    "    def __init__(self, filters, *args, **kwargs):\n",
    "        super().__init__(*args, **kwargs)\n",
    "        self.cbr1 = CBR(filters)\n",
    "        self.pool = layers.MaxPool2D()\n",
    "        self.cbr2 = CBR(filters)\n",
    "        self.cbr3 = CBR(filters)\n",
    "        self.add = layers.Add()\n",
    "\n",
    "    def call(self, x):\n",
    "        x = self.cbr1(x)\n",
    "        x = self.pool(x)\n",
    "        y = self.cbr2(x)\n",
    "        y = self.cbr3(y)\n",
    "        return self.add([x, y])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "metric-transformation",
   "metadata": {},
   "outputs": [],
   "source": [
    "i = layers.Input((32, 32, 3))\n",
    "prep = CBR(64, name='prep')(i)\n",
    "r1 = ResBlock(128, name='ResBlock1')(prep)\n",
    "c1 = CBR(256)(r1)\n",
    "p1 = layers.MaxPool2D()(c1)\n",
    "r2 = ResBlock(512, name='ResBlock2')(p1)\n",
    "p2 = layers.MaxPool2D(4, 4)(r2)\n",
    "f1 = layers.Flatten()(p2)\n",
    "o = layers.Dense(10)(f1)\n",
    "\n",
    "m = keras.Model(inputs=[i], outputs=[o])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "sexual-morrison",
   "metadata": {},
   "outputs": [],
   "source": [
    "m.compile(optimizer='adam', loss=keras.losses.SparseCategoricalCrossentropy(\n",
    "    from_logits=True), metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "formal-processor",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/20\n",
      "196/196 [==============================] - 373s 2s/step - loss: 1.9044 - accuracy: 0.4591 - val_loss: 0.9635 - val_accuracy: 0.6641\n",
      "Epoch 2/20\n",
      "196/196 [==============================] - 327s 2s/step - loss: 0.7133 - accuracy: 0.7507 - val_loss: 0.7218 - val_accuracy: 0.7570\n",
      "Epoch 3/20\n",
      "196/196 [==============================] - 275s 1s/step - loss: 0.4689 - accuracy: 0.8418 - val_loss: 0.5862 - val_accuracy: 0.8031\n",
      "Epoch 4/20\n",
      "196/196 [==============================] - 333s 2s/step - loss: 0.3282 - accuracy: 0.8898 - val_loss: 0.7234 - val_accuracy: 0.7595\n",
      "Epoch 5/20\n",
      "196/196 [==============================] - 340s 2s/step - loss: 0.2379 - accuracy: 0.9218 - val_loss: 0.5627 - val_accuracy: 0.8165\n",
      "Epoch 6/20\n",
      "196/196 [==============================] - 282s 1s/step - loss: 0.1312 - accuracy: 0.9628 - val_loss: 0.5753 - val_accuracy: 0.8171\n",
      "Epoch 7/20\n",
      "196/196 [==============================] - 351s 2s/step - loss: 0.0749 - accuracy: 0.9814 - val_loss: 0.4856 - val_accuracy: 0.8483\n",
      "Epoch 8/20\n",
      "196/196 [==============================] - 363s 2s/step - loss: 0.0424 - accuracy: 0.9908 - val_loss: 0.7393 - val_accuracy: 0.8080\n",
      "Epoch 9/20\n",
      "196/196 [==============================] - 333s 2s/step - loss: 0.0312 - accuracy: 0.9933 - val_loss: 0.6434 - val_accuracy: 0.8328\n",
      "Epoch 10/20\n",
      "196/196 [==============================] - 343s 2s/step - loss: 0.0272 - accuracy: 0.9941 - val_loss: 0.6731 - val_accuracy: 0.8266\n",
      "Epoch 11/20\n",
      "196/196 [==============================] - 344s 2s/step - loss: 0.0283 - accuracy: 0.9930 - val_loss: 0.6057 - val_accuracy: 0.8322\n",
      "Epoch 12/20\n",
      "196/196 [==============================] - 344s 2s/step - loss: 0.0399 - accuracy: 0.9887 - val_loss: 0.8862 - val_accuracy: 0.7785\n",
      "Epoch 13/20\n",
      "196/196 [==============================] - 293s 1s/step - loss: 0.0544 - accuracy: 0.9829 - val_loss: 0.5386 - val_accuracy: 0.8481\n",
      "Epoch 14/20\n",
      "196/196 [==============================] - 330s 2s/step - loss: 0.0403 - accuracy: 0.9887 - val_loss: 0.6678 - val_accuracy: 0.8265\n",
      "Epoch 15/20\n",
      "196/196 [==============================] - 259s 1s/step - loss: 0.0179 - accuracy: 0.9954 - val_loss: 0.5128 - val_accuracy: 0.8675\n",
      "Epoch 16/20\n",
      "196/196 [==============================] - 325s 2s/step - loss: 0.0040 - accuracy: 0.9996 - val_loss: 0.4737 - val_accuracy: 0.8811\n",
      "Epoch 17/20\n",
      "196/196 [==============================] - 377s 2s/step - loss: 7.8756e-04 - accuracy: 0.9999 - val_loss: 0.4545 - val_accuracy: 0.8862\n",
      "Epoch 18/20\n",
      "196/196 [==============================] - 366s 2s/step - loss: 3.1313e-04 - accuracy: 1.0000 - val_loss: 0.4616 - val_accuracy: 0.8864\n",
      "Epoch 19/20\n",
      "196/196 [==============================] - 328s 2s/step - loss: 2.2352e-04 - accuracy: 1.0000 - val_loss: 0.4656 - val_accuracy: 0.8856\n",
      "Epoch 20/20\n",
      "196/196 [==============================] - 338s 2s/step - loss: 1.7709e-04 - accuracy: 1.0000 - val_loss: 0.4708 - val_accuracy: 0.8864\n"
     ]
    }
   ],
   "source": [
    "his=m.fit(x_train, y_train, batch_size=256, epochs=20, validation_data=(x_test,y_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "numerical-header",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'loss': [1.3008830547332764,\n",
       "  0.6789324879646301,\n",
       "  0.4724298417568207,\n",
       "  0.33828696608543396,\n",
       "  0.22967661917209625,\n",
       "  0.1331091970205307,\n",
       "  0.07575376331806183,\n",
       "  0.043374430388212204,\n",
       "  0.033019959926605225,\n",
       "  0.024506209418177605,\n",
       "  0.03052588924765587,\n",
       "  0.0502503365278244,\n",
       "  0.05280149355530739,\n",
       "  0.037250738590955734,\n",
       "  0.013077755458652973,\n",
       "  0.0026669881772249937,\n",
       "  0.000615376397036016,\n",
       "  0.0002970744390040636,\n",
       "  0.0002191752864746377,\n",
       "  0.00017588911578059196],\n",
       " 'accuracy': [0.5705599784851074,\n",
       "  0.7647200226783752,\n",
       "  0.8386600017547607,\n",
       "  0.8859400153160095,\n",
       "  0.9256399869918823,\n",
       "  0.9599599838256836,\n",
       "  0.9804400205612183,\n",
       "  0.9900000095367432,\n",
       "  0.9924200177192688,\n",
       "  0.994979977607727,\n",
       "  0.9923999905586243,\n",
       "  0.9847400188446045,\n",
       "  0.983299970626831,\n",
       "  0.9891600012779236,\n",
       "  0.9972800016403198,\n",
       "  0.9997599720954895,\n",
       "  0.9999799728393555,\n",
       "  1.0,\n",
       "  1.0,\n",
       "  1.0],\n",
       " 'val_loss': [0.9634549617767334,\n",
       "  0.7218278646469116,\n",
       "  0.5862361192703247,\n",
       "  0.7234069108963013,\n",
       "  0.5627248287200928,\n",
       "  0.5752695202827454,\n",
       "  0.4855743646621704,\n",
       "  0.7392598390579224,\n",
       "  0.6433849930763245,\n",
       "  0.6731374859809875,\n",
       "  0.6057258248329163,\n",
       "  0.88623046875,\n",
       "  0.5385739207267761,\n",
       "  0.667823314666748,\n",
       "  0.5127952098846436,\n",
       "  0.47368091344833374,\n",
       "  0.4544743299484253,\n",
       "  0.4615652859210968,\n",
       "  0.46558651328086853,\n",
       "  0.47081539034843445],\n",
       " 'val_accuracy': [0.6640999913215637,\n",
       "  0.7570000290870667,\n",
       "  0.8030999898910522,\n",
       "  0.7595000267028809,\n",
       "  0.8165000081062317,\n",
       "  0.8170999884605408,\n",
       "  0.8482999801635742,\n",
       "  0.8080000281333923,\n",
       "  0.8327999711036682,\n",
       "  0.8266000151634216,\n",
       "  0.8321999907493591,\n",
       "  0.7785000205039978,\n",
       "  0.8481000065803528,\n",
       "  0.8264999985694885,\n",
       "  0.8675000071525574,\n",
       "  0.8810999989509583,\n",
       "  0.8862000107765198,\n",
       "  0.8863999843597412,\n",
       "  0.8855999708175659,\n",
       "  0.8863999843597412]}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "his.history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "coordinate-detector",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "313/313 [==============================] - 25s 78ms/step - loss: 0.4708 - accuracy: 0.8864\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.47081542015075684, 0.8863999843597412]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m.evaluate(x_test,y_test)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
